export const mergeOptions = options => {
  const mergeRes = {}
  // 合并 mixins
  forEach(optionsMergeStratege, (fn, key) => {
    if (options.mixins?.[key] || options[key]) {
      mergeRes[key] = fn(options.mixins?.[key], options[key])
    }
  })
  return mergeRes
}
export const assert = (condition, msg) => {
  if (!condition) {
    throw new Error(msg)
  }
}
export const optionsMergeStratege = {
  data: (dataFn1, dataFn2) => {
    assert(typeof dataFn2 == 'function', 'data need function')
    return {
      ...dataFn1?.(),
      ...dataFn2()
    }
  },
  props: (props1, props2) => {
    assert(Array.isArray(props1) && Array.isArray(props2), 'props need Array')
    return [...props1, ...props2]
  },
  methods: (methods1, methods2) => {
    assert(
      isPlainObject(methods1) && isPlainObject(methods2),
      'methods need plain object'
    )
    return [...methods1, ...methods2]
  },
  listener(lis) {
    this.listener = lis
  },
  created: (created1, created2) => {
    return created1 || created2
  },
  mounted: (mounted1, mounted2) => {
    return mounted1 || mounted2
  },
  parent(p) {
    return p || {}
  }
}
export const forEach = (obj, fn) => {
  obj &&
    Object.keys(obj).forEach(key => {
      fn(obj[key], key)
    })
}
export const isPlainObject = o =>
  Object.prototype.toString.call(o) == '[object Object]'
export const isArray = o => Array.isArray(o)
export const isFunction = o => typeof o == 'function'
